home *** CD-ROM | disk | FTP | other *** search
- /* Read a World Description File */
-
- /* Original read-world and format by Bernie Roehl, July 1992 */
- /* Rewritten for animation and configuration by Dave Stampe Oct. '92 */
-
- // Massively rewritten to port to VR-386 API by Dave Stampe 9/1/94
- // The .WLD file format is for compatibility with REND386 V5.0,
- // and with "Virtual Reality Creations"
- // FUTURE WORLD LOADING MAY LOOK VERY DIFFERENT, AND BE MUCH BETTER
-
-
- /*
- This code is part of the VR-386 project, created by Dave Stampe.
- VR-386 is a desendent of REND386, created by Dave Stampe and
- Bernie Roehl. Almost all the code has been rewritten by Dave
- Stampre for VR-386.
-
- Copyright (c) 1994 by Dave Stampe:
- May be freely used to write software for release into the public domain
- or for educational use; all commercial endeavours MUST contact Dave Stampe
- (dstampe@psych.toronto.edu) for permission to incorporate any part of
- this software or source code into their products! Usually there is no
- charge for under 50-100 items for low-cost or shareware products, and terms
- are reasonable. Any royalties are used for development, so equipment is
- often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to VR-386 and Dave Stampe,
- and any other authors in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling!
-
- DEVELOPMENT: VR-386 is a effort to develop the process started by
- REND386, improving programmer access by rewriting the code and supplying
- a standard API. If you write improvements, add new functions rather
- than rewriting current functions. This will make it possible to
- include you improved code in the next API release. YOU can help advance
- VR-386. Comments on the API are welcome.
-
- CONTACT: dstampe@psych.toronto.edu
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <alloc.h>
- #include <dos.h> /* delay() */
-
- #include "config.h"
- #include "vr_api.h"
- #include "oldtasks.h"
- #include "intmath.h"
- #include "splits.h"
- #include "pcdevice.h"
- #include "segment.h"
-
- int old_angle_order = 0; /* if non-zero, camera angles are pan,tilt,roll */
-
- extern int do_screen_clear;
- extern int flymode, floormode;
- extern unsigned char palette[];
- extern int npalette;
- extern TASK *tasklist;
-
- extern char *fix_fname(char *fname);
-
- static int keep_around = 0; /* if non-zero, don't use temp for names */
-
-
-
- /**************** NAMED LIST SUPPORT **************/
-
- typedef struct _name NAMEREF;
-
- struct _name {
- char *name;
- void *value;
- NAMEREF *next;
- };
-
- extern void *temp_mem;
- extern long temp_size;
-
- NAMEREF *add_name(NAMEREF **list, char *name, void *value)
- {
- NAMEREF *p;
- /* check if temp usable */
- if (!keep_around && (temp_mem) &&
- (temp_size>(sizeof(NAMEREF)+strlen(name)+1)))
- {
- p = temp_mem;
- temp_mem = ((char *)temp_mem) + sizeof(NAMEREF);
- p->name = temp_mem;
- temp_mem = ((char *)temp_mem) + strlen(name) + 1;
- strcpy(p->name, name);
- temp_size -= sizeof(NAMEREF)+strlen(name)+1;
- }
- else /* use heap */
- {
- temp_mem = NULL;
- if ((p = malloc(sizeof(NAMEREF))) == NULL) return NULL;
- p->name = strdup(name);
- }
- p->value = value;
- p->next = *list;
- *list = p;
- return *list;
- }
-
-
- void del_namelist(NAMEREF *list)
- {
- if (keep_around) return;
- if (temp_mem) return;
- while (list)
- {
- if (list->name) free(list->name);
- free(list);
- list = list->next;
- }
- }
-
- void *find_name(NAMEREF *list, char *name)
- {
- while (list)
- {
- if (!stricmp(list->name, name))
- return list->value;
- list = list->next;
- }
- return NULL;
- }
-
- char *find_value(NAMEREF *list, void *value)
- {
- while (list)
- {
- if (list->value == value)
- return list->name;
- list = list->next;
- }
- return NULL;
- }
-
- unsigned int find_color(NAMEREF *list, char *name)
- {
- if (isdigit(name[0])) /* handle dec/hex color */
- return strtoul(name, NULL, 0);
- if (name[0] == '&') return convert_color(&name[1], NULL);
- return (unsigned)find_name(list, name);
- }
-
-
- /****************** TASK AND CONTROL SUPPORT *************/
-
-
- extern void spinner(), sculspin();
-
- struct {
- char *name;
- void (*fn)();
- } functions[] = { {"spinner", spinner},
- {"sculspin", sculspin},
- {NULL, NULL} };
-
-
- /******************** POLYGON, PLANE NORMAL SUPPORT ***********/
-
- #define LSCALE 536870912.0
-
- void scale3(float a, float b, float c,
- long *ap, long *bp, long *cp)
- {
- float maxim; /* integerize normal */
-
- maxim = (a > 0) ? a : -a; /* BUG IN BC 3.0 fabs()! */
- maxim += (b > 0) ? b : -b;
- maxim += (c > 0) ? c : -c;
- if (maxim > 0.0001)
- {
- maxim /= LSCALE;
- *ap = a/maxim;
- *bp = b/maxim; /* normalize to <3.29> */
- *cp = c/maxim;
- }
- }
-
- void scale4(float a, float b, float c, float d,
- long *ap, long *bp, long *cp, long *dp)
- {
- float maxim; /* integerize normal */
-
- maxim = (a > 0) ? a : -a; /* BUG IN BC 3.0 fabs()! */
- maxim += (b > 0) ? b : -b;
- maxim += (c > 0) ? c : -c;
- maxim += (d > 0) ? d : -d;
- if (maxim > 0.0001)
- {
- maxim /= LSCALE;
- *ap = a/maxim;
- *bp = b/maxim; /* normalize to <3.29> */
- *cp = c/maxim;
- *dp = d/maxim;
- }
- }
-
-
- /* facing normal, points should be in CW sequence */
- /* for axis aligned (+) split directions, use: */
- /* x 0 0 x 100 0 x 0 100 for constant x */
- /* 0 y 0 0 y 100 100 y 0 for constant y */
- /* 0 0 z 100 0 z 0 100 z for constant z */
-
- void points_to_normal( float x1, float y1, float z1,
- float x2, float y2, float z2,
- float x3, float y3, float z3,
- long *ap, long *bp, long *cp )
- {
- float v1x, v1y, v1z, v2x, v2y, v2z;
- float a, b, c; /* compute line equation */
-
- v1x = x2 - x1;
- v1y = y2 - y1;
- v1z = z2 - z1;
- v2x = x3 - x1;
- v2y = y3 - y1;
- v2z = z3 - y1;
- a = (v1y * v2z - v2y * v1z);
- b = (v1x * v2z - v2x * v1z);
- c = (v1x * v2y - v2x * v1y);
- scale3(a, b, c, ap, bp, cp);
- }
-
- void points_to_eqn( float x1, float y1, float z1,
- float x2, float y2, float z2,
- float x3, float y3, float z3,
- long *ap, long *bp, long *cp, long *dp)
- {
- float v1x, v1y, v1z, v2x, v2y, v2z;
- float a, b, c, d; /* compute line equation */
-
- v1x = x2 - x1;
- v1y = y2 - y1;
- v1z = z2 - z1;
- v2x = x3 - x1;
- v2y = y3 - y1;
- v2z = z3 - y1;
- a = (v1y * v2z - v2y * v1z);
- b = (v1x * v2z - v2x * v1z);
- c = (v1x * v2y - v2x * v1y);
- d = -(a*x1 + b*y1 + c*z1); /* normalize to <3.29> */
-
- scale4(a, b, c, d, ap, bp, cp, dp);
- }
-
- void normal_to_plane( float x, float y, float z,
- float nx, float ny, float nz,
- long *ap, long *bp, long *cp, long *dp)
- {
- float a, b, c, d; /* compute line equation */
- /* given normal and point */
- a = nx;
- b = -ny;
- c = nz;
- d = -(a*x + b*y + c*z);
-
- scale4(a, b, c, d, ap, bp, cp, dp);
- }
-
-
-
- /************* WORLD AND CONFIG FILE LOADING **********/
-
- NAMEREF *areas = NULL;
- NAMEREF *maps = NULL;
- NAMEREF *surfdefs = NULL;
- NAMEREF *objectlist = NULL;
- NAMEREF *fixedolist = NULL;
- NAMEREF *figurelist = NULL;
-
- #ifdef ENABLE_STATEMACH
- extern NAMEREF *statelist;
- extern NAMEREF *varlist;
- #endif
-
- void dump_lists(void)
- {
- if(temp_mem) return; /* no need to delete if using temp. RAM */
-
- del_namelist(areas);
- del_namelist(maps);
- del_namelist(surfdefs);
- del_namelist(objectlist);
- del_namelist(fixedolist);
- del_namelist(figurelist);
- #ifdef ENABLE_STATEMACH
- del_namelist(statelist);
- del_namelist(varlist);
- #endif
- }
-
-
- typedef struct _surface SURFACEX;
-
- struct _surface {
- unsigned color;
- char *value;
- SURFACEX *next;
- };
-
-
- static SURFACEPAIR colormap[100]; // color pair table for mapping
-
- int create_map_table(SURFACEX *map) // creates color pair table for mapping
- { // uses 0x80xx map flag for compatibility
- int i = 0;
- SURFACEX *p;
- void *v;
-
- if (map)
- {
-
- for (p = map; p; p = p->next)
- {
- colormap[i].old = p->color | 0x8000;
- if ((v = find_name(surfdefs, p->value)) != NULL)
- colormap[i].new = (unsigned) v;
- else
- colormap[i].new = 0;
- i++;
- }
- }
- return i;
- }
-
-
-
-
- extern char loadpath[];
-
- #define match(a,b) !strnicmp(a, b, strlen(b))
-
-
- OBJECT *find_seg(char *name)
- {
- char *p = NULL;
- OBJECT *obj;
-
- if (name[0]==0) return NULL;
- if ((p = strchr(name, '.')) == NULL)
- {
- if ((obj = find_name(objectlist, name)) == NULL) goto try_seg;
- return obj;
- }
- else
- { // part of figure
- *p++ = '\0';
- try_seg:
- if ((obj = find_name(figurelist, name)) == NULL) return NULL; /* no such figure */
- if (p==NULL) return obj; /* root of figure */
- return find_segment_by_name(obj, p);
- }
- }
-
-
-
- void clean_equals(char *b) // fixes up tokenization of string so
- { // word = word -> word=word
- char *c=b, *d=b; // so it's a hack!
-
- if(!strchr(b,'=')) return;
-
- while(*b) /* scan string: */
- {
- if(*b==' ' || *b=='\t') /* if whitespace: */
- {
- d = b; /* record start */
- while (*b==' ' || *b=='\t') *c++ = *b++; /* copy till end of ws */
- if(*b=='=')
- {
- c = d; /* roll back position */
- *c++ = *b++; /* copy = */
- while (*b==' ' || *b=='\t') b++; /* skip trailing ws */
- }
- }
- else *c++ = *b++;
- }
- *c = 0;
- }
-
-
- // these scan a line for a token
- // but leave the dest unchanged if none found/error
-
- void tokstr(char *c) // return string from line
- {
- char *s = strtok(NULL, " \t,\n#");
- if(s) sscanf(s, "%s",c);
- }
-
-
- void tokstrn(char *c) // return string or null string
- {
- char *s = strtok(NULL, " \t,\n#");
- if(s) sscanf(s, "%s",c);
- else *c = 0;
- }
-
- void tokint(int *i) // return integer
- {
- char *s = strtok(NULL, " \t,\n#");
- if(s) sscanf(s, "%d",i);
- }
-
- void tokhex(unsigned *i)
- {
- char *s = strtok(NULL, " \t,\n#");
- if(s) *i = (unsigned int)strtoul(s, NULL, 0);
- }
-
- void toklong(long *i)
- {
- char *s = strtok(NULL, " \t,\n#");
- if(s) sscanf(s, "%ld",i);
- }
-
- void tokfloat(float *i)
- {
- char *s = strtok(NULL, " \t,\n#");
- if(s) sscanf(s, "%f",i);
- }
-
- void tokangle(long *i)
- {
- float f;
- char *s = strtok(NULL, " \t,\n#");
- if(s)
- {
- sscanf(s, "%f", &f);
- *i = 65536L * f;
- }
- }
-
- char *toks(void)
- {
- char *s = strtok(NULL, " \t,\n#");
- if (s) return "";
- else return s;
- }
-
- static int title_index = 0; // WORLD TITLE goes here
- char *title[25] = { NULL };
-
-
- // LIST OF COMMANDS
-
- static char *commands[] = {
- "loadpath", "palette", "skycolor", "groundcolor", "screencolor",
- "screenclear", "ambient", "worldscale", "flymode", "light",
- "window", "key", "control", "viewframe", "start", "floormode",
- "hither", "yon", "eyespacing", "screendist", "attachview",
- "screenwidth", "convergence", "figure", "object", "stepsize",
- "task", "position", "rotate", "camera", "options",
- "include", "surfacemap", "surface", "surfacedef",
- "split", "splitpt", "area", "floor", "floorpts",
- "ceiling", "ceilingpts", "visfrom",
- "endsplits", "polyobj", "polyobj2", "videodev",
- "mousedev", "headdev", "glovedev", "ptrdev",
- "switchdev", "glovecursor", "ptrcursor", "segaport", "switchport",
- "pgloveport", "pglovetime", "stereoset", "stereotype",
- "stereoleft", "stereoright", "depthtype", "attach", "detach",
- "usemap", "fixedobj",
- #ifdef ENABLE_STATEMACH
- "animation", "state", "if", "do",
- #endif
- "title", "mlight", "segment", "addrep",
- "anglestep",
- "version",
- NULL
- };
-
- enum com_codes {
- c_loadpath = 0, c_palette, c_skycolor, c_groundcolor, c_screencolor,
- c_screenclear, c_ambient, c_worldscale, c_flymode, c_light,
- c_window, c_key, c_control, c_viewframe, c_start, c_floormode,
- c_hither, c_yon, c_eyespacing, c_screendist, c_attachview,
- c_screenwidth, c_convergence, c_figure, c_object, c_stepsize,
- c_task, c_position, c_rotate, c_camera, c_options,
- c_include, c_surfacemap, c_surface, c_surfacedef,
- c_split, c_splitpt, c_area, c_floor, c_floorpts,
- c_ceiling, c_ceilingpts, c_visfrom,
- c_endsplits, c_polyobj, c_polyobj2, c_videodev,
- c_mousedev, c_headdev, c_glovedev, c_ptrdev,
- c_switchdev, c_glovecursor, c_ptrcursor, c_segaport, c_switchport,
- c_pgloveport, c_pglovetime, c_stereoset, c_stereotype,
- c_stereoleft, c_stereoright, c_depthtype, c_attach, c_detach,
- c_usemap, c_fixedobj,
- #ifdef ENABLE_STATEMACH
- c_animation, c_state, c_if, c_do,
- #endif
- c_title, c_mlight, c_segment, c_addrep,
- c_anglestep,
- c_version,
- };
-
-
-
-
- static SURFACEX *current_surface = NULL, *map;
- static SPLIT *current_split = NULL;
-
- static char ps[] = " \t\n,#";
- static char st[] = "%s";
-
- extern long spacestep, anglestep;
-
- static char default_map[100] = "";
-
- LIGHT *std_lights[3]; // default lights for the world
- LIGHT *amb_light;
- LIGHT * light1;
- LIGHT * light2;
-
- void create_default_lights()
- {
- POSE p = {1000, 15000, -5000, 0, 0, 0};
- std_lights[0] = amb_light = create_light(NULL,AMBIENT_LIGHT,64);
- std_lights[1] = light1 = create_light(NULL,POINT_LIGHT,64);
- position_pointlight(light1,&p);
- std_lights[2] = light2 = create_light(NULL,POINT_LIGHT,0);
- p.x = -4000;
- position_pointlight(light2,&p);
- }
-
-
- extern TELEPORT *fnkeyposn[10];
- extern TELEPORT *fnkeyhome[10];
-
- extern OBJECT *body_vehicle_object;
-
-
- void read_world(FILE *in)
- {
- char obuff[256];
- char inbuff[256], *buff, fname[100];
- char surfacemapname[100];
- char *args;
- char *pname;
- int i,cmd;
-
- while (fgets(inbuff, sizeof(inbuff), in))
- {
- strcpy(obuff,inbuff);
- buff = strtok(inbuff,"#");
- for (buff = inbuff; isspace(*buff); ++buff);
- if(buff[0]==0) continue;
- clean_equals(buff);
- for (args = buff+1; isalpha(*args); ++args);
- args++;
- buff = strtok(buff," \t\n");
-
- for (cmd = 0; commands[cmd]; cmd++)
- if (!stricmp(commands[cmd], buff)) break;
- if (commands[cmd] == NULL) continue;
-
- switch(cmd)
- {
- case c_palette:
- {
- FILE *in;
- char *f;
- tokstr(fname);
- if ((in = fopen(f = fix_fname(fname), "rb")) != NULL)
- {
- npalette = fread(palette, 3, 256, in);
- fclose(in);
- }
- else errprintf("Could not load palette '%s'", f);
- }
- break;
-
- case c_attach:
- {
- OBJECT *s, *par;
-
- if ((s = find_seg(strtok(NULL,ps))) == NULL) break;
- if ((par = find_seg(strtok(NULL,ps))) == NULL) break;
- attach_object(s, par, 0);
- update_object(par);
- break;
- }
-
- case c_stepsize:
- toklong(&spacestep);
- break;
-
- case c_anglestep:
- {
- float a;
- tokfloat(&a);
- anglestep = a * 65536L;
- }break;
-
- case c_loadpath:
- tokstr(loadpath);
- break;
-
- case c_skycolor:
- tokhex(&sky_color);
- set_skycolor(sky_color);
- break;
-
- case c_groundcolor:
- tokhex(&ground_color);
- set_groundcolor(ground_color);
- break;
-
- case c_screencolor:
- tokhex(&screen_clear_color);
- break;
-
- case c_screenclear:
- tokint(&do_screen_clear);
- break;
-
- case c_ambient:
- {
- int i;
- tokint(&i);
- set_light_intensity(amb_light,i);
- break;
- }
-
- case c_worldscale:
- default_stereo.world_scaling = 65536.0 * atof(strtok(NULL,ps));
- break;
-
- case c_light:
- {
- char *p;
- POSE pose = DONTCARE_POSE;
- int s;
- COORD x,y,z;
-
- x = atol(strtok(NULL,ps));
- y = atol(strtok(NULL,ps));
- z = atol(strtok(NULL,ps));
- p = strtok(NULL, ps);
- if (isdigit(*p)) s = atoi(p);
- else s = !stricmp(p, "spot");
- if(!s)
- {
- pose.x = x; // treat as location
- pose.y = y;
- pose.z = z;
- position_pointlight(light1,&pose);
- }
- else
- {
- pose.rx = float2angle(x); // treat as angles
- pose.ry = float2angle(y);
- pose.rz = float2angle(z);
- rotate_spotlight(light1,&pose);
- }
- } break;
-
- case c_mlight:
- {
- char *p;
- POSE pose = DONTCARE_POSE;
- int s,i;
- COORD x,y,z;
- char parent[100];
- char *m;
- OBJECT *p_seg;
-
- x = atol(strtok(NULL,ps));
- y = atol(strtok(NULL,ps));
- z = atol(strtok(NULL,ps));
- p = strtok(NULL, ps);
- if (isdigit(*p)) s = atoi(p);
- else s = !stricmp(p, "spot");
- sscanf(strtok(NULL,ps), "%d", &i); /* intensity*128 */
- set_light_intensity(light2,i);
- if(!s)
- {
- pose.x = x; // treat as location
- pose.y = y;
- pose.z = z;
- position_pointlight(light2,&pose);
- }
- else
- {
- pose.rx = float2angle(x); // treat as angles
- pose.ry = float2angle(y);
- pose.rz = float2angle(z);
- rotate_spotlight(light2,&pose);
- }
-
- tokstrn(parent);
- if(parent[0]==0 || !stricmp(parent, "fixed")) break; /* not a moveable light */
-
- if ((m=strchr(parent, '='))!=NULL)
- {
- *m++ = 0;
- add_name(&figurelist, parent, light2->seg); /* record name */
- }
- else m = parent;
-
- p_seg = find_seg(m);
- if(p_seg)
- {
- attach_light(light2, p_seg, 0 );
- update_object(p_seg);
- }
- break;
- }
-
- case c_segment:
- {
- OBJECT *this_seg, *p_seg;
- char parentname[60], *oname, *p;
- long tx = 0, ty = 0, tz = 0, rx = 0, ry = 0, rz = 0;
-
- oname = NULL;
- tokstrn(parentname);
- tokangle(&rx);
- tokangle(&ry);
- tokangle(&rz);
- toklong(&tx);
- toklong(&ty);
- toklong(&tz);
-
- if ((p = strchr(parentname, '=')) != NULL)
- {
- oname = parentname;
- *p++ = '\0';
- }
- else p = parentname;
- p_seg = find_seg(p);
- if ((this_seg = create_invisible_object()) != NULL)
- {
- POSE pose;
- pose.x = tx;
- pose.y = ty;
- pose.z = tz;
- pose.rx = rx;
- pose.ry = ry;
- pose.rz = rz;
- attach_object(this_seg, p_seg, 0);
- set_object_pose(this_seg, &pose);
- update_object(this_seg);
- if (oname) add_name(&figurelist, oname, this_seg);
- }
- }
- break;
-
- case c_camera:
- {
- int n;
- char *c;
- POSE p = ZERO_POSE;
-
- tokint(&n);
- if (n < 1 || n > 10) break;
- if(n==1) goto set_start;
- n--;
- toklong(&(p.x));
- toklong(&(p.y));
- toklong(&(p.z));
- if (old_angle_order)
- {
- tokangle(&(p.ry));
- tokangle(&(p.rx));
- }
- else
- {
- tokangle(&(p.rx));
- tokangle(&(p.ry));
- }
- tokangle(&(p.rz));
-
- if(!fnkeyposn[n])
- fnkeyposn[n] = create_teleport();
- teleport_set_here(fnkeyposn[n], &p);
- teleport_set_vehicle(fnkeyposn[n],NULL,NULL);
-
- if(!fnkeyhome[n])
- fnkeyhome[n] = create_teleport();
- teleport_set_here(fnkeyhome[n], &p);
- teleport_set_vehicle(fnkeyhome[n],NULL,NULL);
-
- // tokangle(&(v->zoom)); // ignore for now
- // toklong(&(v->hither));
- // toklong(&(v->yon));
-
- } break;
-
- case c_start:
- set_start:
- {
- float zoom = 0.0;
-
- toklong(&initial_body_pose.x);
- toklong(&initial_body_pose.y);
- toklong(&initial_body_pose.z);
- if(old_angle_order)
- {
- tokangle(&initial_body_pose.ry);
- tokangle(&initial_body_pose.rx);
- }
- else
- {
- tokangle(&initial_body_pose.rx);
- tokangle(&initial_body_pose.ry);
- }
- tokangle(&initial_body_pose.rz);
-
- tokfloat(&zoom);
- if(zoom>16.0) zoom = 16.0;
- if(zoom>0.5)
- set_camera_zoom(default_camera, float2scale(zoom));
-
- *body_pose = initial_body_pose;
- if(!fnkeyposn[0])
- fnkeyposn[0] = create_teleport();
- teleport_set_vehicle(fnkeyposn[0],body_vehicle_object,NULL);
- teleport_set_here(fnkeyposn[0], &initial_body_pose);
- if(!fnkeyhome[0])
- fnkeyhome[0] = create_teleport();
- teleport_set_here(fnkeyhome[0], &initial_body_pose);
- teleport_set_vehicle(fnkeyhome[0],body_vehicle_object,NULL);
- break;
- }
-
- case c_attachview:
- {
- OBJECT *vehicle = NULL;
- char parentname[60];
- tokstrn(parentname);
- vehicle = find_seg(parentname);
- if(vehicle) connect_body(vehicle);
-
- if(!fnkeyposn[0])
- fnkeyposn[0] = create_teleport();
- teleport_set_here(fnkeyposn[0], &initial_body_pose);
- teleport_set_vehicle(fnkeyposn[0],body_vehicle_object,NULL);
-
- if(!fnkeyhome[0])
- fnkeyhome[0] = create_teleport();
- teleport_set_here(fnkeyhome[0], &initial_body_pose);
- teleport_set_vehicle(fnkeyhome[0],body_vehicle_object,NULL);
- }
- break;
-
- case c_hither:
- {
- COORD h = atol(strtok(NULL,ps));
- if(h<1) h=1;
- set_camera_hither(default_camera,h);
- break;
- }
- case c_yon:
- {
- COORD y = atol(strtok(NULL,ps));
- if(y>530000000L) y=530000000L;
- set_camera_yon(default_camera,y);
- break;
- }
-
- case c_title:
- if((args!=NULL)&&(args[0]!=0)&&(title_index<22))
- {
- char s[200];
- sscanf(args, "%s", s);
- if(strlen(args)>36) args[36] = 0;
- if(!stricmp(s,"memory"))
- {
- sprintf(s, "Memory Left: %ld", coreleft());
- args = s;
- }
- title[title_index++] = strdup(args);
- title[title_index] = NULL;
- }break;
-
- #ifdef ENABLE_STATEMACH
- /* ANIMATION PARSER */
- case c_animation:
- parse_ani();
- break;
- case c_state:
- parse_state();
- break;
- case c_if:
- parse_if();
- break;
- case c_do:
- parse_do();
- break;
- #endif
- case c_figure:
- {
- char filename[60], parentname[60], *oname, *p;
- float sx = 1, sy = 1, sz = 1;
- FILE *fig;
- POSE pose = ZERO_POSE;
-
- parentname[0] = '\0';
- oname = NULL;
- sscanf(strtok(NULL,ps), st, filename);
- tokfloat(&sx);
- tokfloat(&sy);
- tokfloat(&sz);
- tokangle(&pose.rx);
- tokangle(&pose.ry);
- tokangle(&pose.rz);
- toklong(&pose.x);
- toklong(&pose.y);
- toklong(&pose.z);
- tokstrn(parentname);
- add_ext(filename, "fig");
- if ((p = strchr(filename, '=')) != NULL)
- {
- oname = filename;
- *p++ = '\0';
- }
- else
- p = filename;
- if ((fig = fopen(pname = fix_fname(p), "r")) != NULL)
- {
- SEGMENT *this_seg, *p_seg;
- p_seg = find_seg(parentname);
- this_seg = load_figure_as_object(fig, default_objlist, NULL, 0, sx, sy, sz);
- if (this_seg != NULL)
- {
- add_objlist_to_world(default_objlist);
- if(p_seg)attach_object(this_seg,p_seg,0);
- set_object_pose(this_seg, &pose);
- update_object(this_seg);
- }
- fclose(fig);
- if (seg_error(NULL))
- {
- errprintf("%s in figure file '%s'\n", seg_error(NULL), pname);
- break;
- }
- if (oname) add_name(&figurelist, oname, this_seg);
- }
- else
- errprintf( "Could not open '%s'", pname);
- } break;
-
- case c_fixedobj:
- case c_object:
- {
- char mappings[100], *p, filename[100], *oname, parentname[100];
- float sx = 1, sy = 1, sz = 1;
- ANGLE rx = 0, ry = 0, rz = 0;
- COORD tx = 0, ty = 0, tz = 0;
- int dt = 0, nmaps = 0;
- int nobjs = 0;
- FILE *plg;
- OBJECT *obj;
-
- sscanf(strtok(NULL,ps), st, filename);
- add_ext(filename, "plg");
-
- tokfloat(&sx);
- tokfloat(&sy);
- tokfloat(&sz);
-
- tokangle(&rx);
- tokangle(&ry);
- tokangle(&rz);
- toklong(&tx);
- toklong(&ty);
- toklong(&tz);
-
- tokint(&dt);
-
- tokstrn(mappings);
- map = find_name(maps, mappings);
- if (!map)
- map = find_name(maps, default_map);
- nmaps = create_map_table(map);
-
- tokstrn(parentname);
- if (cmd == c_fixedobj || (current_split) ) // on split: force to fixed!
- strcpy(parentname, "fixed");
-
- if ((p = strchr(filename, '=')) != NULL)
- {
- oname = filename;
- *p++ = '\0';
- }
- else
- {
- oname = NULL;
- p = filename;
- }
-
- if ((plg = fopen(pname = fix_fname(p), "r")) != NULL)
- {
- POSE pose;
- POSE zpose = ZERO_POSE; // for load of moveable
- // choose load offsets
- POSE *loadp = (!stricmp(parentname, "fixed")) ? &pose: &zpose ;
-
- pose.x=tx; pose.y=ty; pose.z=tz;
- pose.rx=rx; pose.ry=ry; pose.rz=rz;
-
- nobjs = load_plg_to_objlist(plg, default_objlist, 100, loadp, sx, sy, sz, dt);
- if(nobjs)
- {
- if(nmaps&&nobjs)
- objlist_remap_surface(default_objlist, colormap, nmaps,
- MAP_ALL_MASK, MAP_ALL_MASK);
-
- if (stricmp(parentname, "fixed"))
- {
- SEGMENT *s, *p = NULL;
-
- p = find_seg(parentname);
- obj = convert_objlist_to_moveable_object(default_objlist);
- if(obj && p) attach_object(obj, p, 0);
- set_object_pose(obj, &pose);
- update_object(obj);
- }
- else obj = first_in_objlist(default_objlist);
- add_objlist_to_world(default_objlist);
-
- if (oname) // add name NOW in case file didn't load
- {
- if (stricmp(parentname, "fixed"))
- add_name(&objectlist, oname, obj);
- else
- add_name(&fixedolist, oname, obj);
- }
- }
- if (plg_error(NULL))
- {
- errprintf("%s in file %s\n", plg_error(NULL), pname);
- break;
- }
- }
- else
- {
- errprintf("Could not open '%s'", pname);
- break;
-
- }
- fclose(plg);
- } break;
-
- case c_addrep:
- {
- char mappings[100], *p, filename[100], *oname;
- float sx = 1, sy = 1, sz = 1;
- int defsize = 0;
- FILE *plg;
- OBJECT *obj, sobj;
- POSE pose = ZERO_POSE;
- int nmaps = 0;
-
- sscanf(strtok(NULL,ps), st, filename);
- add_ext(filename, "plg");
-
- tokfloat(&sx);
- tokfloat(&sy);
- tokfloat(&sz);
- tokangle(&pose.rx);
- tokangle(&pose.ry);
- tokangle(&pose.rz);
- toklong(&pose.x);
- toklong(&pose.y);
- toklong(&pose.z);
- tokint(&defsize);
- tokstrn(mappings);
-
- map = find_name(maps, mappings);
- nmaps = create_map_table(map);
-
- if ((p = strchr(filename, '=')) == NULL) break;
- oname = filename;
- *p++ = '\0';
- if((obj = find_seg(oname))==NULL)
- {
- if(!(obj = find_name(fixedolist, oname))) break;
- }
- if ((plg = fopen(pname = fix_fname(p), "r")) != NULL)
- {
- while ((obj = load_extra_plg_representation(plg, obj, &pose, sx, sy, sz, defsize)) != NULL)
- if (obj)
- {
- if(nmaps)
- masked_remap_object_surface(obj, colormap, nmaps,
- MAP_ALL_MASK, MAP_ALL_MASK, FALSE);
- physical_update_object(obj); /* update world coords, etc */
- }
- if (plg_error(NULL))
- {
- errprintf("%s in file %s\n", plg_error(NULL), pname);
- break;
- }
- }
- else
- {
- errprintf( "Could not open '%s'", pname);
- break;
- }
- fclose(plg);
- } break;
-
- case c_task:
- {
- char taskname[100], param[100];
- long period;
- int i;
- void *data;
-
- sscanf(strtok(NULL,ps), st, taskname);
- period = atol(strtok(NULL,ps)) * 6L; // FASTER CLK
- strcpy(param, strtok(NULL,"\n"));
- for (i = 0; functions[i].name; ++i)
- if (!stricmp(taskname, functions[i].name))
- {
- add_task(&tasklist, functions[i].fn, period, param);
- break;
- }
- } break;
-
- case c_position:
- {
- OBJECT *obj;
- char oname[100];
- long x, y, z;
-
- strcpy(oname, strtok(NULL,ps));
- x = atol(strtok(NULL,ps));
- y = atol(strtok(NULL,ps));
- z = atol(strtok(NULL,ps));
- if ((obj = find_seg(oname)) != NULL)
- {
- POSE p = DONTCARE_POSE;
- p.x = x;
- p.y = y;
- p.z = z;
- set_object_pose(obj, &p);
- update_object(obj);
- }
- }break;
-
- case c_rotate:
- {
- OBJECT *obj;
- char oname[100];
- float rx, ry, rz;
-
- strcpy(oname,strtok(NULL,ps));
- rx = atof(strtok(NULL,ps));
- ry = atof(strtok(NULL,ps));
- rz = atof(strtok(NULL,ps));
- if ((obj = find_seg(oname)) != NULL)
- {
- POSE p = DONTCARE_POSE;
- p.rx = float2angle(rx);
- p.ry = float2angle(ry);
- p.rz = float2angle(rz);
- set_object_pose(obj, &p);
- update_object(obj);
- }
- }
- break;
-
- case c_include:
- {
- char fname[100];
- FILE *in;
- char *f;
- strcpy(fname,strtok(NULL,ps));
- if ((in = fopen(f = fix_fname(fname), "r")) != NULL)
- {
- read_world(in);
- fclose(in);
- }
- else
- errprintf("Could not open '%s'as include file", f);
- }break;
-
- case c_surfacemap:
- {
- /* starts a new map of color numbers to surface names */
- strcpy(surfacemapname,strtok(NULL,ps));
- current_surface = NULL;
- } break;
-
- case c_surface:
- {
- SURFACEX *p;
- /* maps a color number to a surface name */
- if ((p = malloc(sizeof(SURFACEX))) != NULL) // create list element
- {
- char buf2[40];
-
- if (current_surface == NULL) // add name for color map (first)
- add_name(&maps, surfacemapname, p);
- else
- current_surface->next = p; // or just add
- current_surface = p;
- p->next = NULL;
- p->color = strtoul(strtok(NULL,ps), NULL, 0); // get value
- strcpy(buf2,strtok(NULL,ps));
- p->value = strdup(buf2);
- }
- }
- break;
-
- case c_surfacedef:
- { /* maps a surface name to an internal color value */
- char sname[100], svalue[20];
-
- strcpy(sname,strtok(NULL,ps)); // add to list
- strcpy(svalue,strtok(NULL,ps));
- add_name(&surfdefs, sname, (void *) convert_color(svalue, NULL));
- } break;
-
- case c_split:
- {
- float x, y, z, nnx, nny, nnz;
- long nx, ny, nz;
- unsigned flags = 0;
-
- x = atof(strtok(NULL,ps));
- y = atof(strtok(NULL,ps));
- z = atof(strtok(NULL,ps));
- nnx = atof(strtok(NULL,ps));
- nny = atof(strtok(NULL,ps));
- nnz = atof(strtok(NULL,ps));
- tokhex(&flags);
- scale3(nnx, nny, nnz, &nx, &ny, &nz);
- add_split_to_world(x, y, z, nx, ny, nz, flags);
- }break;
-
- case c_splitpt:
- {
- float x1, x2, x3, y1, y2, y3, z1, z2, z3;
- long nx, ny, nz;
- unsigned flags = 0;
-
- x1 = atof(strtok(NULL,ps));
- y1 = atof(strtok(NULL,ps));
- z1 = atof(strtok(NULL,ps));
- x2 = atof(strtok(NULL,ps));
- y2 = atof(strtok(NULL,ps));
- z2 = atof(strtok(NULL,ps));
- x3 = atof(strtok(NULL,ps));
- y3 = atof(strtok(NULL,ps));
- z3 = atof(strtok(NULL,ps));
- flags = strtoul(strtok(NULL,ps), NULL, 0);
- points_to_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3, &nx, &ny, &nz);
- add_split_to_world(x1, y1, z1, nx, ny, nz, flags);
- } break;
-
- case c_area:
- {
- long x, y, z;
- void *what_area();
- char areaname[100];
- AREA *a;
-
- x = atol(strtok(NULL,ps));
- y = atol(strtok(NULL,ps));
- z = atol(strtok(NULL,ps));
- sscanf(strtok(NULL,ps), st, areaname);
- add_name(&areas, areaname, a=what_area(global_world_root, x, y, z));
- set_area_name(a, areaname);
- }break;
-
- case c_endsplits:
- end_of_world_splits();
- break;
-
- case c_polyobj:
- case c_polyobj2:
- {
- char map[100], map2[100];
- OBJECT *obj;
- POLY *poly;
- unsigned color;
- int nv = 0;
- int i;
- long x[18], y[18], z[18];
-
- map[0] = '\0';
- nv = atoi(strtok(NULL,ps));
- tokstrn(map);
- if (cmd==c_polyobj2) tokstrn(map2);
-
- if (nv > 18) nv = 18;
- for(i=0;i<nv;i++)
- {
- x[i] = atol(strtok(NULL,ps));
- y[i] = atol(strtok(NULL,ps));
- z[i] = atol(strtok(NULL,ps));
- }
- i = (cmd==c_polyobj2) ? 2 : 1 ;
- obj = create_fixed_object(nv, i, nv*i);
- if (obj)
- {
- char *p;
- if ((p = strtok(NULL, ps)) != NULL)
- set_object_sorting(obj, atoi(p));
- if (map)
- color = (unsigned) find_color(surfdefs, map);
- poly = add_poly(obj, color, nv);
- for (i = 0; i < nv; i++)
- {
- add_vertex(obj, x[i], y[i], z[i]);
- add_point(obj, poly, nv-i-1);
- }
- if (cmd == c_polyobj2)
- {
- if (map2)
- color = (unsigned) find_color(surfdefs, map2);
- poly = add_poly(obj, color, nv);
- for (i = 0; i < nv; i++)
- {
- add_point(obj, poly, i);
- }
- }
- compute_object(obj);
- add_object_to_world(obj);
- }
- }break;
- }
- }
- return;
- }
-